home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
3_0
/
MENUDEMO
/
MENU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-09
|
6KB
|
258 lines
/*
* menu.c - MenuDemo: a demo of a custom Menu Definition.
*
* How to build this program:
* 1) In the "crushproj" project, create the CODE resource, "crush.mdef".
* 2) Run RMaker on the file "menu.r".
* 3) Use ResEdit to edit "crushproj.rsrc", changing the proc-id of each
* menu from 0 (the stock MDEF) to 400 (our custom MDEF's resource ID).
* 4) In the "menuproj" project, Build the Application, MenuDemo.
*/
#include <MacTypes.h>
#include <Quickdraw.h>
#include <MemoryMgr.h>
#include <WindowMgr.h>
#include <DialogMgr.h>
#include <MenuMgr.h>
#include <EventMgr.h>
#include <DeskMgr.h>
#include <ControlMgr.h>
#include <TextEdit.h>
#include <PackageMgr.h>
#include <ToolboxUtil.h>
#include <pascal.h>
/*
* LINKED_MDEF - Set to '1' if the MDEF is really a subroutine that we're
* testing; Set to '0' otherwise.
*
* This definition makes it easy to debug a new MDEF by having this program
* call our menu definition subroutine directly
* (rather than calling MenuSelect()).
*
* To use this feature, add the menu definition code to this program's project
* (so it gets linked in) and change the MDEF's entry point name from "main"
* to "mymenu".
*
* When you're done debugging, change LINKED_MDEF to '0', change the MDEF's
* entry name back to "main", and remove the MDEF's code from this project.
*/
#define LINKED_MDEF 0
/**********
* Garden-variety declarations for this program follow.
* they're not really part of the demo.
**********/
#define APPLEMENU 1 /* Menu ID for Apple menu */
#define FILEMENU 2 /* ...File menu */
#define DEMOMENU 3 /* ...Demo menu */
#define LASTMENU 3 /* Number of menus */
#define DLG_ABOUT 256 /* ResID of the About... dialog */
MenuHandle mymenus[LASTMENU + 1]; /* menus[1..LASTMENU] */
#define maxStackSize 8192 /* max size of our stack */
/*
* screenport - used to keep the current port from ever dangling.
* This is a port for the whole screen.
*/
GrafPtr screenport;
/***************
* The following routines are just boilerplate.
* They aren't part of the virus detection code.
***************/
/*
* main() - run the program.
*/
main()
{
long *stackbaseptr; /* points to current stack base */
int i;
/*
* Initialize our memory,
* then init the Toolbox managers (order is important).
*/
stackbaseptr = (long *) 0x908;
SetApplLimit((Ptr) (*stackbaseptr - maxStackSize));
MaxApplZone();
MoreMasters();
MoreMasters();
InitGraf(&thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs((ProcPtr) 0);
DILoad();
SetEventMask(everyEvent - keyUpMask);
InitCursor();
GetWMgrPort(&screenport);
SetPort(screenport);
/*
* Setup our menus, then do nothing until we quit.
*/
for (i = 1; i <= LASTMENU; i++) {
mymenus[i] = GetMenu(i);
InsertMenu(mymenus[i], 0);
}
DrawMenuBar();
while (doevent())
;
InitCursor();
SetEventMask(everyEvent - keyUpMask);
}
/*
* doevent() - one loop through the main event handler
*/
int /* "do another event" */
doevent()
{
EventRecord myevent; /* the event to handle */
WindowPtr whichwindow; /* Points to window of MouseDown */
char whichchar; /* the character typed */
long menucommand; /* a menu command to do (menu + item) */
int windowcode; /* What mouse was in when event posted */
int userdone; /* True when user wants to exit program */
userdone = FALSE;
SystemTask(); /* give the system a moment of time */
if (!GetNextEvent(everyEvent, &myevent)) {
/* We're idle. */
} else if ((myevent.modifiers & cmdKey) &&
(myevent.what == keyDown || myevent.what == autoKey)) {
/*
* It's a command-key keystroke.
* (command keystrokes are handled here since dialogs can't)
*/
whichchar = (char) (myevent.message & charCodeMask);
menucommand = MenuKey(whichchar);
userdone = docommand(menucommand);
} else if (IsDialogEvent(&myevent)) {
/* here's where we'd handle modeless dialog events */
} else {
switch (myevent.what) {
case mouseDown: /* a mouse click someplace */
windowcode = FindWindow(myevent.where, &whichwindow);
if (windowcode == inMenuBar) {
menucommand = MenuSelect(myevent.where);
userdone = docommand(menucommand);
break;
} else {
#if LINKED_MDEF
int theitem;
theitem = dumbmenu(myevent.where);
#endif
}
break;
}
}
return(!userdone);
}
/*
* docommand() - handle a command given through a menu selection.
*/
int /* "the command was 'quit' */
docommand(mresult)
long mresult; /* the command to execute (a menu item) */
{
int themenu; /* menu the mouse chose */
int theitem; /* item in that menu */
int returns; /* value to be returned */
short itemhit;
DialogPtr reportptr;
returns = FALSE;
themenu = HiWord(mresult);
theitem = LoWord(mresult);
switch (themenu) {
case APPLEMENU: /* Tell about the program */
reportptr = GetNewDialog(DLG_ABOUT, (char *) 0, (long) -1);
ModalDialog((ProcPtr) 0, &itemhit);
DisposDialog(reportptr);
break;
case FILEMENU: /* quit */
returns = TRUE;
break;
}
HiliteMenu(0);
return(returns);
}
#if LINKED_MDEF
/*
* dumbmenu() - pretend to be MenuSelect(),
* calling the appropriate operations in the MDEF we're testing.
*
* This arrangement lets us quickly debug a new MDEF under Lightspeed C
* without going to the hassle of generating a real MDEF each time we
* make a change.
*/
int /* the item # */
dumbmenu(pt)
Point pt; /* mouse-down (global coords) */
{
MenuHandle menuh; /* the menu we're working with */
Rect menurect; /* the rect bounding the menu */
int theitem; /* the selected item number */
Rect tmprect;
pascal void mymenu(); /* the name of our MDEF subroutine */
menuh = mymenus[DEMOMENU];
menurect.top = 0;
menurect.left = 0;
menurect.bottom = 0;
menurect.right = 0;
theitem = 0;
mymenu((int) mSizeMsg, menuh, &menurect, pt, &theitem);
menurect.top = 50;
menurect.left = 30;
menurect.bottom = menurect.top + (*menuh)->menuHeight;
menurect.right = menurect.left + (*menuh)->menuWidth;
EraseRect(&menurect);
tmprect = menurect;
InsetRect(&tmprect, -1, -1);
FrameRect(&tmprect);
MoveTo(tmprect.left + 2, tmprect.bottom);
LineTo(tmprect.right, tmprect.bottom);
LineTo(tmprect.right, tmprect.top + 2);
mymenu((int) mDrawMsg, menuh, &menurect, pt, &theitem);
while (StillDown()) {
GetMouse(&pt);
LocalToGlobal(&pt);
mymenu((int) mChooseMsg, menuh, &menurect, pt, &theitem);
}
EraseRect(&menurect);
}
#endif